package com.leaf.u_jvm;

/**
 * 一次自我拯救的演示
 * 1.对象可以在被GC时自我拯救
 * 2.这种自救的机会只有一次，因为对象的finalize()方法最多只会被系统自动调用一次
 *  正常运行结果：
 *  finalize method excuted
 *  yes, I am still alive
 *  no, I am dead
 *  
 *  finalize()方法确实执行了，但是第一次拯救成功，第二次失败了
 *  
 *  
 * 注意：这个案例只做演示使用，切记在实际中使用，因为finalize()方法的不确定性很大，它的优先级很低，容易受影响
 * 可以dubug看看运行结果
 * 
 * 可以是try-finally或者其它方式
 */
public class FinalizeEscapeGC {

	public static FinalizeEscapeGC SAVE_HOOK = null;
	
	public void isAlive(){
		System.out.println("yes, I am still alive");
	}
	
	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		System.out.println("finalize method excuted");
		FinalizeEscapeGC.SAVE_HOOK = this;
	}
	
	public static void main(String[] args) throws Throwable {
		SAVE_HOOK = new FinalizeEscapeGC();
		
		//对象第一次成功拯救自己
		SAVE_HOOK = null;
		System.gc();
		//因为finalize方法优先级很低，所以暂停0.5秒等待它
		Thread.sleep(500);
		if(SAVE_HOOK != null){
			SAVE_HOOK.isAlive();
		} else {
			System.out.println("no, I am dead");
		}
		
		
		//下面这段代码和上面一样，但是这次自救失败了
		SAVE_HOOK = null;
		System.gc();
		//因为finalize方法优先级很低，所以暂停0.5秒等待它
		Thread.sleep(500);
		if(SAVE_HOOK != null){
			SAVE_HOOK.isAlive();
		} else {
			System.out.println("no, I am dead");
		}
	}
	
	
}
